package com.cz.mydao.util;

import com.cz.mydao.constant.SqlKey;
import com.cz.mydao.wrapper.Condition;

import java.util.List;

/**
 * @descriptions: 工具类
 * @author: Joker.
 * @date: 2024/12/24 9:09
 * @version: 1.0
 */
public class MyUtil {

    /**
     * 构建where sql
     *
     * @param conditions 条件集合
     * @param sqlBuilder sql语句
     */
    public static void buildWhereSql(List<Condition> conditions, StringBuilder sqlBuilder) {
        sqlBuilder.append(SqlKey.WHERE);
        // 遍历条件集合
        for (int index = 0; index < conditions.size(); index++) {
            Condition condition = conditions.get(index);
            // 通过运算符判断是哪种操作 拼接sql
            buildConditionSql(sqlBuilder, condition);
            // 如果后面还有条件，加 and
            if (index < conditions.size() - 1) {
                sqlBuilder.append(SqlKey.AND);
            }
        }
    }

    /**
     * 通过运算符判断是哪种操作 拼接sql
     * @param sqlBuilder sql
     * @param condition 条件
     */
    private static void buildConditionSql(StringBuilder sqlBuilder, Condition condition) {
        switch (condition.getOperator()) {
            case SqlKey.IN:
                // 拼接IN操作
                buildIn(sqlBuilder, condition);
                break;
            case SqlKey.BETWEEN:
                // 拼接 between and 操作
                buildBetweenAnd(sqlBuilder, condition);
                break;
            default:
                // 其他操作则通用
                sqlBuilder.append(MyUtil.fieldNameToColumnName(condition.getField())).append(condition.getOperator()).append(SqlKey.QUESTION_MARK);
        }
    }

    /**
     * 拼接 between and 操作
     * @param sqlBuilder sql
     * @param condition  between and 条件
     */
    private static void buildBetweenAnd(StringBuilder sqlBuilder, Condition condition) {
        sqlBuilder.append(MyUtil.fieldNameToColumnName(condition.getField()))
                .append(SqlKey.BETWEEN)
                .append(SqlKey.QUESTION_MARK)
                .append(SqlKey.AND)
                .append(SqlKey.QUESTION_MARK);
    }

    /**
     * 拼接in操作
     *
     * @param sqlBuilder sql
     * @param condition  in条件
     */
    private static void buildIn(StringBuilder sqlBuilder, Condition condition) {
        List<Object> values = condition.getValues();
        sqlBuilder.append(MyUtil.fieldNameToColumnName(condition.getField()))
                .append(SqlKey.IN)
                .append(SqlKey.LEFT_BRACKET)
                // 将多个值按照 , 间隔
                .append(String.join(SqlKey.COMMA, values.stream().map(v -> SqlKey.QUESTION_MARK).toArray(String[]::new)))
                .append(SqlKey.RIGHT_BRACKET);
    }

    /**
     * 将驼峰命名法的字段转为 _的列名  如: deptCode -> dept_code
     *
     * @param fieldName 要转换的字段名
     * @return 转换后的列名
     */
    public static String fieldNameToColumnName(String fieldName) {
        if (fieldName == null || fieldName.isEmpty()) {
            return fieldName;
        }

        StringBuilder columnName = new StringBuilder();
        // 遍历每个字符
        for (char c : fieldName.toCharArray()) {
            // 如果是大写字符，则转换为小写并且前面加一个_
            if (Character.isUpperCase(c)) {
                columnName.append("_").append(Character.toLowerCase(c));
            } else {
                // 小写，直接追加
                columnName.append(c);
            }
        }
        return columnName.toString();
    }
}
